package com.xiaoshuidi.cloud.module.rooms.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaoshuidi.cloud.framework.common.exception.ServiceException;
import com.xiaoshuidi.cloud.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.xiaoshuidi.cloud.framework.common.pojo.CommonResult;
import com.xiaoshuidi.cloud.framework.oss.core.OosFileService;
import com.xiaoshuidi.cloud.module.rooms.controller.admin.pricing.vo.HousePricingExportResp;
import com.xiaoshuidi.cloud.module.rooms.controller.admin.roomdevice.vo.ReadingOrderExportVO;
import com.xiaoshuidi.cloud.module.rooms.controller.admin.roomdevice.vo.ReadingOrderImportVO;
import com.xiaoshuidi.cloud.module.rooms.mapper.RoomSdiotReadingOrderMapper;
import com.xiaoshuidi.cloud.module.rooms.mapper.RoomSdiotReadingOrderRecordMapper;
import com.xiaoshuidi.cloud.module.rooms.mq.listener.ReadingOrderImportListener;
import com.xiaoshuidi.cloud.module.rooms.pojo.RoomSdiotReadingOrder;
import com.xiaoshuidi.cloud.module.rooms.pojo.RoomSdiotReadingOrderRecord;
import com.xiaoshuidi.cloud.module.rooms.service.RoomSdiotReadingOrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class RoomSdiotReadingOrderServiceImpl extends ServiceImpl<RoomSdiotReadingOrderMapper, RoomSdiotReadingOrder> implements RoomSdiotReadingOrderService {

    private final RoomSdiotReadingOrderMapper roomSdiotReadingOrderMapper;

    private final RoomSdiotReadingOrderRecordMapper roomSdiotReadingOrderRecordMapper;

    @Autowired
    private OosFileService oosFileService;

    @Override
    public IPage<RoomSdiotReadingOrder> readingOrderPageList(Integer pageSize, Integer pageNum, String feeType, String roomName, Boolean isConcentrated) {
        IPage<RoomSdiotReadingOrder> page = new Page(pageNum, pageSize);
        List<RoomSdiotReadingOrder> roomSdiotReadingOrderList = roomSdiotReadingOrderMapper.readingOrderPageList(feeType, roomName, isConcentrated);
        int startIndex = (pageNum - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, roomSdiotReadingOrderList.size());
        List<RoomSdiotReadingOrder> pageRecords = roomSdiotReadingOrderList.subList(startIndex, endIndex);
        page.setTotal(roomSdiotReadingOrderList.size());
        page.setRecords(pageRecords);
        return page;
    }

    @Override
    public HousePricingExportResp readingOrderExport(Integer pageSize, Integer pageNum, String feeType, String roomName, Boolean isConcentrated) {
        IPage<RoomSdiotReadingOrder> pageResult = readingOrderPageList(pageSize, pageNum, feeType, roomName, isConcentrated);
        String fileName = "抄表数据导出.xlsx";
        List<RoomSdiotReadingOrder> list = pageResult.getRecords();
        if (CollectionUtil.isNotEmpty(list)) {
            List<ReadingOrderExportVO> readingOrderExportVos = new ArrayList<>();
            for (RoomSdiotReadingOrder order : list) {
                QueryWrapper<RoomSdiotReadingOrderRecord> qw = new QueryWrapper<>();
                qw.eq("reading_order_id", order.getId());
                List<RoomSdiotReadingOrderRecord> records = roomSdiotReadingOrderRecordMapper.selectList(qw);
                if (CollectionUtil.isNotEmpty(records)) {
                    for (RoomSdiotReadingOrderRecord record : records) {
                        ReadingOrderExportVO vo = new ReadingOrderExportVO();
                        vo.setRoomName(order.getRoomName());
                        vo.setTenantName(order.getTenantName());
                        vo.setFeeType(order.getFeeType());
                        vo.setPrice(record.getPrice());
                        vo.setLastTimeReadingTime(record.getLastTimeReadingTime());
                        vo.setLastTimeReadingCount(record.getLastTimeReadingCount());
                        vo.setCurrentReadingTime(record.getCurrentReadingTime());
                        vo.setCurrentReadingCount(record.getCurrentReadingCount());
                        vo.setDueDate(record.getDueDate());
                        vo.setFee(record.getFee());
                        if (record.getLastTimeReadingTime() == null) {
                            vo.setBillingCycle("" + record.getCurrentReadingTime());
                        } else {
                            vo.setBillingCycle(record.getLastTimeReadingTime() + "-" + record.getCurrentReadingTime());
                        }
                        readingOrderExportVos.add(vo);
                    }
                }

            }
            ExcelWriter excelWriter = EasyExcel.write(fileName, ReadingOrderExportVO.class).build();
            WriteSheet sheet = EasyExcel.writerSheet("sheet1").head(ReadingOrderExportVO.class).build();
            excelWriter.write(readingOrderExportVos, sheet);
            excelWriter.finish();
        }
        String url = oosFileService.oosUploadFile(new File(fileName));
        HousePricingExportResp resp = new HousePricingExportResp();
        resp.setUrl(url);
        resp.setFileName("抄表数据导出.xlsx");
        return resp;
    }

    /**
     * 抄表记录导入
     *
     * @param fileUrl
     * @return
     */
    @Override
    public CommonResult<String> readingOrderImport(String fileUrl) {
        try (InputStream is = oosFileService.oosDownloadFile(fileUrl)) {
            //todo @黄光辉 要考虑大批量数据导入时 OOM
            EasyExcel.read(is, ReadingOrderImportVO.class, new ReadingOrderImportListener(roomSdiotReadingOrderMapper, roomSdiotReadingOrderRecordMapper)).sheet().doRead();
        } catch (IOException e) {
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "文件不存在");
        } catch (ExcelDataConvertException e) {
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "数据格式不正确");
        }
        return CommonResult.success("抄表记录导入成功");
    }


}
